/*
 * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * https://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.aabte.commons.rest.api;

import com.aabte.commons.rest.errorcode.IApiErrorCode;
import com.aabte.commons.rest.exception.ApiException;
import java.util.Collection;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.ObjectUtils;

/**
 * REST API 业务断言
 * <p>参考：org.junit.Assert</p>
 *
 * @author hubin
 * @since 2018-06-05
 */
public class Assert {

    protected Assert() {
        // to do noting
    }

    /**
     * 大于O
     */
    public static void gtZero(Integer num, IApiErrorCode errorCode) {
        if (num == null || num <= 0) {
            fail(errorCode);
        }
    }

    /**
     * 大于等于O
     */
    public static void geZero(Integer num, IApiErrorCode errorCode) {
        if (num == null || num < 0) {
            fail(errorCode);
        }
    }

    /**
     * num1大于num2
     */
    public static void gt(Integer num1, Integer num2, IApiErrorCode errorCode) {
        if (num1 <= num2) {
            fail(errorCode);
        }
    }

    /**
     * num1大于等于num2
     */
    public static void ge(Integer num1, Integer num2, IApiErrorCode errorCode) {
        if (num1 < num2) {
            fail(errorCode);
        }
    }

    /**
     * obj1 eq obj2
     */
    public static void eq(Object obj1, Object obj2, IApiErrorCode errorCode) {
        if (!obj1.equals(obj2)) {
            fail(errorCode);
        }
    }

    public static void isTrue(boolean condition, IApiErrorCode errorCode) {
        if (!condition) {
            fail(errorCode);
        }
    }

    public static void isFalse(boolean condition, IApiErrorCode errorCode) {
        if (condition) {
            fail(errorCode);
        }
    }

    public static void isNull(IApiErrorCode errorCode, Object... conditions) {
        if (ObjectUtils.anyNotNull(conditions)) {
            fail(errorCode);
        }
    }

    public static void notNull(IApiErrorCode errorCode, Object... conditions) {
        if (ObjectUtils.anyNotNull(conditions)) {
            fail(errorCode);
        }
    }

    /**
     * 失败结果
     *
     * @param errorCode 异常错误码
     */
    public static void fail(IApiErrorCode errorCode) {
        throw new ApiException(errorCode);
    }

    public static void fail(boolean condition, IApiErrorCode errorCode) {
        if (condition) {
            fail(errorCode);
        }
    }

    public static void fail(String message) {
        throw new ApiException(message);
    }

    public static void fail(boolean condition, String message) {
        if (condition) {
            fail(message);
        }
    }

    public static void noNullElements(Object[] array, IApiErrorCode errorCode) {
        if (array != null) {
            for (Object element : array) {
                if (element == null) {
                    fail(errorCode);
                }
            }
        }
    }

    public static void notEmpty(Collection<?> collection, IApiErrorCode errorCode) {
        if (CollectionUtils.isNotEmpty(collection)) {
            fail(errorCode);
        }
    }

    public static void notEmpty(Map<?, ?> map, IApiErrorCode errorCode) {
        if (MapUtils.isEmpty(map)) {
            fail(errorCode);
        }
    }

    public static void isInstanceOf(Class<?> type, Object obj, IApiErrorCode errorCode) {
        notNull(errorCode, type);
        if (!type.isInstance(obj)) {
            fail(errorCode);
        }
    }

    public static void isAssignable(Class<?> superType, Class<?> subType, IApiErrorCode errorCode) {
        notNull(errorCode, superType);
        if (subType == null || !superType.isAssignableFrom(subType)) {
            fail(errorCode);
        }
    }
}
